;#
;# convolve_asm.S
;#
;# Perform the convolution between two vectors
;# 
;# Oded Rosen, 2011   
;#

	.text
	.globl Convolve
	
	.arm
	
;#************************************************************************
;#
;#  FUNCTION: Convolve 
;#
;#  PURPOSE:
;#     Perform the convolution between two vectors x[] and h[] and
;#     write the result in the vector y[]. All vectors are of length L
;#     and only the first L samples of the convolution are computed.
;#
;#  DESCRIPTION:
;#     The convolution is given by
;#
;#          y[n] = sum_{i=0}^{n} x[i] h[n-i],        n=0,...,L-1
;#
;#************************************************************************/

	;# inputs / outputs:
	x			.req r0		;# (i)  : input vector, 16 bit array
    h			.req r1		;# (i)  : impulse response, 16 bit array
    y			.req r2		;# (o)  : output vector, 16 bit array
    L			.req r3		;# (i)  : vector size, 16 bit
	
	;# temp values:
	i			.req r4		;# 16 bit
	n			.req r5		;# 16 bit
	s			.req r6		;# 32 bit
	xi			.req r7		;# 16 bit
	ni			.req r8		;# 16 bit
	hni			.req r9		;# 16 bit
	
	

Convolve:

		;# Stack current values:
		PUSH		{r4-r9}		;# stack
		
		MOV			n,#0

c_n_loop:
		MOV			s,#0			;# s = 0;
		MOV			i,#0			;# i = 0;
		
c_i_loop:
		SUB			ni,n,i
		LDRSH		xi,[x,+i]		;# s = L_mac (s, x[i], h[n - i]);
		LDRSH		hni,[h,+ni]		;# s = L_mac (s, x[i], h[n - i]);
		SMULBB 		xi,xi,hni		;# s = L_mac (s, x[i], h[n - i]);
		QDADD		s,s,xi			;# s = L_mac (s, x[i], h[n - i]);
		
		ADD			i,i,#2
		CMP			i,n
		BLE			c_i_loop
;# c_i_loop ends

		LSL			s,s,#3 			;# s = L_shl (s, 3);
		ASR			s,#16			;# y[n] = extract_h (s);
		STRH		s,[y,+n]		;# y[n] = extract_h (s); 

		ADD			n,n,#2
		CMP			n,L,LSL #1
		BLT			c_n_loop
;# c_n_loop ends
		
		;# Unstack values and return:
		POP			{r4-r9}		;# unstack
		BX			lr				;# return
